# ========================================================== # System-Wide Outlook OST Repair Script # ========================================================== # Use Case: # Repairs Outlook OST-related sync problems for ALL users by: # 1. Closing Outlook # 2. Searching all user profiles # 3. Finding OST files # 4. Backing up OST files # 5. Deleting OST files # 6. Allowing Outlook to recreate fresh OST files # # Backup Retention: # - Maintains only latest 3 backups per OST file # - Oldest backup will be removed automatically # ========================================================== Write-Host "=========================================" Write-Host " System-Wide Outlook OST Repair Started" Write-Host "=========================================" # ---------------------------------------------------------- # Step 1 - Close Outlook # ---------------------------------------------------------- Write-Host "`n[INFO] Closing Outlook..." Get-Process OUTLOOK -ErrorAction SilentlyContinue | ForEach-Object { $_.CloseMainWindow() | Out-Null # Wait up to 10 seconds if (!$_.WaitForExit(10000)) { Write-Host "[INFO] Force closing Outlook..." $_ | Stop-Process -Force } } # ---------------------------------------------------------- # Step 2 - Get All User Profiles # ---------------------------------------------------------- Write-Host "`n[INFO] Searching all user profiles..." $ExcludedUsers = @( "Public", "Default", "Default User", "All Users" ) # Add users passed through script arguments for ($i = 0; $i -lt $args.Count; $i++) { if (![string]::IsNullOrWhiteSpace($args[$i])) { $ExcludedUsers += $args[$i] } } # Get profiles excluding specified users $UserProfiles = Get-ChildItem "C:\Users" -Directory | Where-Object { $_.Name -notin $ExcludedUsers } if ($UserProfiles.Count -eq 0) { Write-Host "[ERROR] No user profiles found." exit } # ---------------------------------------------------------- # Step 3 - Search, Backup and Delete OST Files # ---------------------------------------------------------- foreach ($Profile in $UserProfiles) { $OutlookPath = Join-Path $Profile.FullName "AppData\Local\Microsoft\Outlook" Write-Host "`n-----------------------------------------" Write-Host "[INFO] Checking profile: $($Profile.Name)" Write-Host "[INFO] Path: $OutlookPath" if (!(Test-Path $OutlookPath)) { Write-Host "[WARNING] Outlook folder not found." continue } $OSTFiles = Get-ChildItem -Path $OutlookPath -Filter *.ost -ErrorAction SilentlyContinue if ($OSTFiles.Count -eq 0) { Write-Host "[WARNING] No OST files found." continue } Write-Host "`n[INFO] Processing OST files..." foreach ($File in $OSTFiles) { try { # -------------------------------------------------- # Backup Folder # -------------------------------------------------- $BackupRoot = Join-Path $OutlookPath "OST_Backups" if (!(Test-Path $BackupRoot)) { New-Item -Path $BackupRoot -ItemType Directory | Out-Null } # Create timestamp backup file $Timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $BackupFileName = "$($File.BaseName)_$Timestamp.ost" $BackupPath = Join-Path $BackupRoot $BackupFileName # -------------------------------------------------- # Backup OST File # -------------------------------------------------- Write-Host "[INFO] Creating backup:" Write-Host " $BackupFileName" Copy-Item -Path $File.FullName -Destination $BackupPath -Force # -------------------------------------------------- # Maintain Only Latest 3 Backups # -------------------------------------------------- $ExistingBackups = Get-ChildItem -Path $BackupRoot -Filter "$($File.BaseName)_*.ost" | Sort-Object LastWriteTime -Descending if ($ExistingBackups.Count -gt 3) { $BackupsToDelete = $ExistingBackups | Select-Object -Skip 3 foreach ($OldBackup in $BackupsToDelete) { Write-Host "[INFO] Removing old backup:" Write-Host " $($OldBackup.Name)" Remove-Item -Path $OldBackup.FullName -Force } } # -------------------------------------------------- # Delete Original OST File # -------------------------------------------------- Write-Host "[INFO] Deleting OST file:" Write-Host " $($File.Name)" Remove-Item -Path $File.FullName -Force Write-Host "[SUCCESS] OST repaired successfully." } catch { Write-Host "[ERROR] Failed processing file:" Write-Host " $($File.Name)" Write-Host $_.Exception.Message } } } # ---------------------------------------------------------- # Step 4 - Restart Outlook # ---------------------------------------------------------- Write-Host "`n[INFO] Restarting Outlook..." try { Start-Process "outlook.exe" Write-Host "[SUCCESS] Outlook restarted." } catch { Write-Host "[WARNING] Could not automatically start Outlook." Write-Host $_.Exception.Message } # ---------------------------------------------------------- # Step 5 - Completion Message # ---------------------------------------------------------- Write-Host "`n=========================================" Write-Host " System-Wide OST Repair Completed" Write-Host "=========================================" Write-Host "`nNext Steps:" Write-Host "1. Open Outlook." Write-Host "2. Outlook will create fresh OST files." Write-Host "3. Mailbox data will sync automatically."